class User < ActiveRecord::Base
  has_one :blog
  
  with_options(:order => 'published_at DESC') do |this|
    this.has_many :articles
    this.has_many :comments
  end
  
  composed_of :name,
              :class_name => UserName,
              :mapping => 
              [    
                [:first_name, :first],
                [:last_name, :last]
              ]
  
  @@salt = '0c77a19d9466af1b7f963a5ab999e05adb179125'
  cattr_accessor :salt
  
  def add_article(options)
    articles.build(options)
  end
  
  def self.authenticate(name, pass)
    find(:first,
         :conditions => ["(unique_name = ? OR email = ?) AND password = ?", name, name, sha1(pass)])
  end
  
  def password=(newpass)
    @password = newpass
  end
  
  def password(cleartext = nil)
    if cleartext
      @password.to_s
    else
      @password || read_attribute("password")
    end
  end
  
  before_create :crypt_password
  
  def crypt_password
    write_attribute "password", self.class.sha1(password(true))
    @password = nil
  end
  
  before_update :crypt_unless_empty

  # If the record is updated we will check if the password is empty.
  # If its empty we assume that the user didn't want to change his
  # password and just reset it to the old value.
  def crypt_unless_empty
    if password(true).empty?
      user = self.class.find(self.id)
      self.password = user.password
    else
      write_attribute "password", self.class.sha1(password(true))
      @password = nil
    end
  end
  
  validates_presence_of :first_name, :last_name, :unique_name, :password, :email
  validates_format_of :email, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i
  validates_uniqueness_of :unique_name, :email
  
  protected
  
  def self.sha1(pass)
    Digest::SHA1.hexdigest("#{salt}--#{pass}--")
  end
end
